#include <sys/time.h>
#include "conn_helper.h"
#include "crc32.h"

#define SERVER_HEAD_TIMESTAMP(stamp) \
	do {\
		struct timeval now; \
		gettimeofday(&now, NULL); \
		stamp = ((uint64_t)now.tv_sec << 32) | ((uint64_t)now.tv_usec); \
	}while(0)

#define SERIALIZE_BUFF_LEN 64 * 1024

int send_connect_res(struct LSI* lsi, lsi_ip_t dest, int32_t address, int result)
{
	struct server_head_t server_head;
	server_head.address = address;
	server_head.cmd = ID_S2CONN_RES_CONNECT;
	server_head.pkg_crc = result;
	server_head.pkg_len = 0;
	SERVER_HEAD_TIMESTAMP(server_head.timestamp);
	static char buff[SERIALIZE_BUFF_LEN];
	size_t bufflen = SERIALIZE_BUFF_LEN;
	int ret = serialize_server_head(&server_head, buff, &bufflen);
	assert(0 == ret);
	return lsi_send(lsi, dest, buff, sizeof(server_head));
}

int send_disconnect_ntf(struct LSI* lsi, lsi_ip_t dest, int32_t address, int reason)
{
	struct server_head_t server_head;
	server_head.address = address;
	server_head.cmd = ID_S2CONN_NTF_DISCONN;
	server_head.pkg_crc = reason;
	server_head.pkg_len = 0;
	SERVER_HEAD_TIMESTAMP(server_head.timestamp);
	static char buff[SERIALIZE_BUFF_LEN];
	size_t bufflen = SERIALIZE_BUFF_LEN;
	int ret = serialize_server_head(&server_head, buff, &bufflen);
	assert(0 == ret);
	return lsi_send(lsi, dest, buff, sizeof(server_head));
}

int send_pkg_ntf(struct LSI* lsi, lsi_ip_t dest, int32_t address,  serializer sr, void* pkg_ptr)
{
	static char buff[SERIALIZE_BUFF_LEN];
	struct server_head_t server_head;
	server_head.address = address;
	server_head.cmd = ID_S2CONN_NTF_PKG;
	SERVER_HEAD_TIMESTAMP(server_head.timestamp);

	/* serialize pkg */
	char* buff_pkg = buff + sizeof(server_head);
	size_t pkg_serial_len = SERIALIZE_BUFF_LEN - sizeof(server_head);
	int ret = sr(pkg_ptr, buff_pkg, &pkg_serial_len);
	assert(0 == ret);

	/* serialize proto head */
	server_head.pkg_len = pkg_serial_len;
	server_head.pkg_crc = crc32(buff_pkg, pkg_serial_len);
	size_t bufflen = sizeof(server_head);
	ret = serialize_server_head(&server_head, buff, &bufflen);
	assert(0 == ret && bufflen == sizeof(server_head));

	/* send */
	return lsi_send(lsi, dest, buff, sizeof(server_head) + pkg_serial_len);
}

